package com.yuandian.customer.perception.service.impl;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.customer_perception.constant.StatTypeEnum;
import com.yuandian.api.customer_perception.po.AddExportListParams;
import com.yuandian.api.customer_perception.po.BusinessOverviewParams;
import com.yuandian.api.customer_perception.po.LowFrequencyOverviewParams;
import com.yuandian.api.customer_perception.vo.BusinessDataInfo;
import com.yuandian.api.customer_perception.vo.BusinessTreeDataVo;
import com.yuandian.api.customer_perception.vo.ExportListVo;
import com.yuandian.api.customer_perception.vo.LowFrequencyOverviewVo;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.customer.perception.mapper.ExportListMapper;
import com.yuandian.customer.perception.mapper.LowFrequencyOverviewMapper;
import com.yuandian.customer.perception.service.ILowFrequencyOverviewService;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 说明：低频受理业务概况service实现
 *
 * @Author yanjun
 * @Date 2021年4月14日 上午9:19:49
 */
@Service
public class LowFrequencyOverviewServiceImpl implements ILowFrequencyOverviewService {

	@Autowired
	private LowFrequencyOverviewMapper lowFrequencyOverviewMapper;

	@Autowired
	private ExportListMapper exportListMapper;


    /**
     * 查询低频受理业务概况列表
     *
     * @param params 低频受理业务概况请求对象
     * @return 通用分页对象
     */
//    @DS("khgzData")
    @Override
    public PageDataInfo queryLowFrequencyOverviewList(LowFrequencyOverviewParams params) {
//		根据前端传过来的周期时间(会比查询范围的最后一天增加一天,如9.30号会变成10.1 12:00:00)
        Long cycleTimeUsec = params.getCycleTimeUsec();
        LocalDate cycleTime = Instant.ofEpochMilli(cycleTimeUsec).atZone(ZoneOffset.ofHours(8)).toLocalDate();
        //查询周时，默认查询指定时间的下周一
        LocalDateTime type1DateTime = LocalDateTime.of(cycleTime, LocalTime.MIN).with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        LocalDateTime type2DateTime = LocalDateTime.of(cycleTime, LocalTime.MIN).with(TemporalAdjusters.firstDayOfMonth());
        LocalDateTime type3DateTime = LocalDateTime.of(cycleTime.minusMonths(3), LocalTime.MIN).with(TemporalAdjusters.firstDayOfMonth());
        if (params.getStatisticsType() == 1) {
            //当统计周期为1时，查询当前时间的周一
            type1DateTime = LocalDateTime.of(cycleTime, LocalTime.MIN).with(DayOfWeek.MONDAY);
            type2DateTime = LocalDateTime.of(cycleTime, LocalTime.MIN).minusDays(7).with(TemporalAdjusters.firstDayOfMonth());
        } else if (params.getStatisticsType() == 2||params.getStatisticsType() ==3) {
            //如果统计周期为2，当前月份减去统计时间月份大于=1，意思就是说前端传统计周期时间，当前月份减去统计周期时间大于=0
            Date cycleDate = new Date(params.getCycleTimeUsec());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
            String cycleDateStr = simpleDateFormat.format(cycleDate);

            Date nowDate = new Date();
            String nowDateStr = simpleDateFormat.format(nowDate);
            try {
                cycleDate = simpleDateFormat.parse(cycleDateStr);
                nowDate = simpleDateFormat.parse(nowDateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }

            if (nowDate.compareTo(cycleDate) == 0) {
                //当统计周期为2时，且查询当前时间上月的数据时，查询指定时间的周一
                type1DateTime = LocalDateTime.of(cycleTime.minusDays(1), LocalTime.MIN).with(DayOfWeek.SUNDAY).minusDays(-1);
            }

        }


        Instant type1Instant = type1DateTime.toInstant(ZoneOffset.of("+8"));
        Instant type2Instant = type2DateTime.toInstant(ZoneOffset.of("+8"));
        Instant type3Instant = type3DateTime.toInstant(ZoneOffset.of("+8"));

        Long type1Usec = type1Instant.toEpochMilli() * 1000;
        Long type2Usec = type2Instant.toEpochMilli() * 1000;
        Long type3Usec = type2Instant.toEpochMilli() * 1000;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(Date.from(type2Instant));
        int monthDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        calendar.setTime(Date.from(type3Instant));
        int d1 = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.MONTH, 1);
        int d2 = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.MONTH, 1);
        int d3 = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        int threeMonthDay = d1 + d2 + d3;

        params.setWeekCycleTime(type1Usec);
        params.setMonthCycleTime(type2Usec);
        params.setThreeMonthCycleTime(type3Usec);
        params.setMonthDay(monthDay);
        params.setThreeMonthDay(threeMonthDay);

        Integer statisticsType = params.getStatisticsType();
        if (params.getOrderByColumn()==null||("").equals(params.getOrderByColumn())){
            params.setIsAsc("desc");
            if (statisticsType == 1) {
                params.setOrderByColumn("weekCount");
            } else if (statisticsType == 2) {
                params.setOrderByColumn("monthCount");
            } else if (statisticsType == 3) {
                params.setOrderByColumn("threeMonthCount");
            }
        }


        Page<LowFrequencyOverviewVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        List<LowFrequencyOverviewVo> list = lowFrequencyOverviewMapper.queryLowFrequencyOverviewList(params, page);
        return new PageDataInfo(page, list);
    }

    /**
     * 添加至导出列表
     *
     * @param params 添加至导出列表请求参数
     * @return 通用返回对象
     */
//    @DS("khgzData")
    @Override
    public R addExportList(AddExportListParams params) {
        // 校验是否同一时间段存在相同业务
        Integer statisticsType = params.getStatisticsType();
        String acceptStateStr = "week_accept_state";
        String cycleTimeUsecStr = "week_cycle_time_usec";
        if (statisticsType == 1) {
            acceptStateStr = "week_accept_state";
            cycleTimeUsecStr = "week_cycle_time_usec";
        } else if (statisticsType == 2) {
            acceptStateStr = "month_accept_state";
            cycleTimeUsecStr = "month_cycle_time_usec";
        } else if (statisticsType == 3) {
            acceptStateStr = "three_month_accept_state";
            cycleTimeUsecStr = "three_month_cycle_time_usec";
        }

        List<ExportListVo> exportList = params.getExportList();
        LowFrequencyOverviewParams p = new LowFrequencyOverviewParams();
        for (ExportListVo l : exportList) {
            if (statisticsType == 1) {
                p.setCycleTimeUsec(l.getWeekCycleTime());
                p.setAcceptStateList(Collections.singletonList(l.getWeekAcceptState()));
            } else if (statisticsType == 2) {
                p.setCycleTimeUsec(l.getMonthCycleTime());
                p.setAcceptStateList(Collections.singletonList(l.getMonthAcceptState()));
            } else if (statisticsType == 3) {
                p.setCycleTimeUsec(l.getThreeMonthCycleTime());
                p.setAcceptStateList(Collections.singletonList(l.getThreeMonthAcceptState()));
            }

            p.setSystemIdList(Collections.singletonList(l.getSystemId()));
            p.setBusinessCodeList(Collections.singletonList(l.getBusinessCode()));
            if (exportListMapper.queryExportListCount(p, acceptStateStr, cycleTimeUsecStr) > 0) {
                return R.failed(-1, "同一统计时间内业务已存在导出列表！");
            }
        }
        // 添加至导出列表
        lowFrequencyOverviewMapper.addExportList(params);
        return R.ok("success");
    }

    /**
     * 添加所有数据至导出列表
     *
     * @param params 添加至导出列表请求参数
     * @return 通用返回对象
     */
//    @DS("khgzData")
    @Override
    public R addAllExportList(LowFrequencyOverviewParams params) {
        LowFrequencyOverviewParams p = new LowFrequencyOverviewParams();
        Integer statisticsType = params.getStatisticsType();
        p.setStatisticsType(statisticsType);

        // 查询出相应的数据列表
        params.setPageNum(1);
        params.setPageSize(-1);
        List<LowFrequencyOverviewVo> lowFrequencyOverviewVoList =(List<LowFrequencyOverviewVo>) this.queryLowFrequencyOverviewList(params).getData();
        List<ExportListVo> voList = new ArrayList<>();
        // 遍历该列表数据是否已加入导出列表, 若已加入则删除相关数据
        for (LowFrequencyOverviewVo res : lowFrequencyOverviewVoList) {
            if (statisticsType == 1) {
                p.setCycleTimeUsec(res.getWeekCycleTime());
                p.setAcceptStateList(Arrays.asList(res.getWeekAcceptState()));
            } else if (statisticsType == 2) {
                p.setCycleTimeUsec(res.getMonthCycleTime());
                p.setAcceptStateList(Arrays.asList(res.getMonthAcceptState()));
            } else if (statisticsType == 3) {
                p.setCycleTimeUsec(res.getThreeMonthCycleTime());
                p.setAcceptStateList(Arrays.asList(res.getThreeMonthAcceptState()));
            }

            p.setSystemIdList(Arrays.asList(new Integer[]{res.getSystemId()}));
            p.setBusinessCodeList(Arrays.asList(new String[]{res.getBusinessCode()}));

            // 校验是否同一时间段存在相同业务
            String acceptStateStr = "week_accept_state";
            String cycleTimeUsecStr = "week_cycle_time_usec";
            if (statisticsType == 1) {
                acceptStateStr = "week_accept_state";
                cycleTimeUsecStr = "week_cycle_time_usec";
            } else if (statisticsType == 2) {
                acceptStateStr = "month_accept_state";
                cycleTimeUsecStr = "month_cycle_time_usec";
            } else if (statisticsType == 3) {
                acceptStateStr = "three_month_accept_state";
                cycleTimeUsecStr = "three_month_cycle_time_usec";
            }
            if (!(exportListMapper.queryExportListCount(p, acceptStateStr, cycleTimeUsecStr) > 0)) {
                ExportListVo exportListVo = new ExportListVo();
                exportListVo.setSystemId(res.getSystemId());
                exportListVo.setSystemName(res.getSystemName());
                exportListVo.setBusinessCode(res.getBusinessCode());
                exportListVo.setBusinessName(res.getBusinessName());
                exportListVo.setWeekAcceptState(res.getWeekAcceptState());
                exportListVo.setMonthAcceptState(res.getMonthAcceptState());
                exportListVo.setThreeMonthAcceptState(res.getThreeMonthAcceptState());
                exportListVo.setWeekCount(res.getWeekCount());
                exportListVo.setAvgWeekCount(res.getAvgWeekCount());
                exportListVo.setMonthCount(res.getMonthCount());
                exportListVo.setAvgMonthCount(res.getAvgMonthCount());
                exportListVo.setAvgThreeMonthCount(res.getAvgThreeMonthCount());
                exportListVo.setThreeMonthCount(res.getThreeMonthCount());
                exportListVo.setWeekCycleTime(res.getWeekCycleTime());
                exportListVo.setMonthCycleTime(res.getMonthCycleTime());
                exportListVo.setThreeMonthCycleTime(res.getThreeMonthCycleTime());
                exportListVo.setLastTime(res.getLastTime() == null ? null : res.getLastTime());
                exportListVo.setSuggest(res.getSuggest() == null ? null : res.getSuggest());
                voList.add(exportListVo);
            }

        }
		if (voList == null || voList.size() <= 0) {
			return R.ok("success");
		}
		AddExportListParams paramsExport = new AddExportListParams();
		paramsExport.setStatisticsType(params.getStatisticsType());
		paramsExport.setExportList(voList);

		// 添加至导出列表
		lowFrequencyOverviewMapper.addExportList(paramsExport);
		return R.ok("success");
    }

	/**
	 * 业务概况-树形图
	 * @param params
	 * @return
	 */
//	@DS("khgzData")
	@Override
	public R tree(BusinessOverviewParams params) {
		if (params.getSystemId() == null) {
			return R.failed(-1, "请选择相关系统");
		}

		// 设置表名
		params.setTableName(StatTypeEnum.valueOf(params.getType()).getTableName());
		// 设置时间周期
		LocalDateTime dateTime = null;
		if (params.getType() == 1) {
			dateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY);
		} else {
			dateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(TemporalAdjusters.firstDayOfMonth());
		}
		if (StringUtils.isNotBlank(params.getCycleTimeUsec())){
            params.setCycleTimeUsec(params.getCycleTimeUsec() * 1000);
        }else{
            params.setCycleTimeUsec(dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() * 1000);
        }


		// 查询数据
		List<BusinessDataInfo> list = lowFrequencyOverviewMapper.queryTreeDataList(params);
		if (list == null) {
			return R.ok();
		}

		Map<String, Object> dataMap = new HashMap<>();
		int total = 0;
		LinkedHashMap<String, BusinessTreeDataVo> dataLinkedHashMap = new LinkedHashMap<>();
		for (BusinessDataInfo businessDataInfo : list) {
			int acceptState = businessDataInfo.getAcceptState();
			total += businessDataInfo.getCount();
			String[] split = businessDataInfo.getBusinessName().split("-");
			String rootName = split[0];
			BusinessTreeDataVo rootData = dataLinkedHashMap.get(rootName);
			if (rootData == null) {
				rootData = new BusinessTreeDataVo();
				rootData.setBusinessCode(businessDataInfo.getBusinessCode());
				rootData.setBusinessName(rootName);
				rootData.setSystemId(businessDataInfo.getSystemId());
				rootData.setSystemName(businessDataInfo.getSystemName());
				rootData.setTotal(businessDataInfo.getCount());
				// 设置状态 受理状态 1:正常 2:低频 3:空置
				rootData.setAcceptState(businessDataInfo.getAcceptState());
			} else {
				rootData.setTotal(rootData.getTotal() + businessDataInfo.getCount());
				if (acceptState == 3) {
					rootData.setAcceptState(acceptState);
				} else if (acceptState == 2 && rootData.getAcceptState() == 1) {
					rootData.setAcceptState(2);
				}
			}
			LinkedHashMap<String, BusinessTreeDataVo> rootDataChildren = rootData.getChildrenData();
			if (rootDataChildren == null) {
				rootDataChildren = new LinkedHashMap<>();
			}
			BusinessTreeDataVo parentData = rootData;
			if (split.length > 0) {
				for (int i = 1; i < split.length; i++) {
					String childrenName = split[i];
					LinkedHashMap<String, BusinessTreeDataVo> children = parentData.getChildrenData();
					if (children == null) {
						children = new LinkedHashMap<>();
						parentData.setChildrenData(children);
					}
					BusinessTreeDataVo childData = children.get(childrenName);
					if (childData == null) {
						childData = new BusinessTreeDataVo();
						childData.setBusinessCode(businessDataInfo.getBusinessCode());
						childData.setBusinessName(childrenName);
						childData.setSystemId(businessDataInfo.getSystemId());
						childData.setSystemName(businessDataInfo.getSystemName());
						childData.setTotal(businessDataInfo.getCount());
						// 设置状态
						childData.setAcceptState(businessDataInfo.getAcceptState());
						children.put(childrenName, childData);
					}else {
						childData.setTotal(childData.getTotal() + businessDataInfo.getCount());
						if (acceptState == 3) {
							childData.setAcceptState(acceptState);
						} else if (acceptState == 2 && childData.getAcceptState() == 1) {
							childData.setAcceptState(2);
						}
					}
					parentData = childData;
				}
				dataLinkedHashMap.put(rootName, rootData);
			}
		}
		dataMap.put("total", total);
		// 处理为最终返回数据
		List<BusinessTreeDataVo> treeDataList = new ArrayList<>();
		Iterator<Map.Entry<String, BusinessTreeDataVo>> iterator = dataLinkedHashMap.entrySet().iterator();
		while (iterator.hasNext()) {
			BusinessTreeDataVo businessTreeDataVo = iterator.next().getValue();
			List<BusinessTreeDataVo> businessTreeDataVoList = realData(businessTreeDataVo);
			businessTreeDataVo.setChildren(businessTreeDataVoList);
			businessTreeDataVo.setChildrenData(null);
			treeDataList.add(businessTreeDataVo);
		}
		// 更具前台选择的业务集合，过滤掉其他数据
		List<BusinessTreeDataVo> res = new ArrayList<>();
		if (params.getBusinessCodeList() != null && params.getBusinessCodeList().length > 0) {
			List<String> businessList = Arrays.asList(params.getBusinessCodeList());
			res = treeDataList.stream()
					.filter(b -> businessList.contains(b.getBusinessCode()))
					.collect(Collectors.toList());
			dataMap.put("treeData", res);
			return R.ok(dataMap);
		}
		dataMap.put("treeData", treeDataList);
		return R.ok(dataMap);
	}

    /**
     * 递归处理子节点
     *
     * @param parentData
     * @return
     */
    private List<BusinessTreeDataVo> realData(BusinessTreeDataVo parentData) {
        List<BusinessTreeDataVo> list = new ArrayList<>();
        LinkedHashMap<String, BusinessTreeDataVo> childrenData = parentData.getChildrenData();
        if (childrenData != null) {
            Iterator<Map.Entry<String, BusinessTreeDataVo>> iterator = childrenData.entrySet().iterator();
            while (iterator.hasNext()) {
                BusinessTreeDataVo value = iterator.next().getValue();
                if (value.getChildrenData() != null) {
                    List<BusinessTreeDataVo> childList = realData(value);
                    value.setChildren(childList);
                } else {
                    value.setChildren(new ArrayList<>());
                }
                list.add(value);
                value.setChildrenData(null);
            }
        }
        return list;
    }
}
